/*
 * @Author: huangyingli
 * @Date: 2023-02-23 00:52:11
 * @LastEditors: huangyingli
 * @LastEditTime: 2023-02-28 13:00:00
 * @Description:
 */
import React, { useMemo, Suspense } from 'react';

import JSXStyle from 'styled-jsx/style';

const fetchComponent = async (name) => {
  const text = await fetch(`http://127.0.0.1:8081/${name}`, {
    mode: 'cors',
  }).then((a) => {
    if (!a.ok) {
      throw new Error('Network response was not ok');
    }
    return a.text();
  });
  const module = getParsedModule(text, name);
  return { default: module.exports };
};

const packages = {
  react: React,
  'styled-jsx/style': JSXStyle,
};

const getParsedModule = (code) => {
  let module = {
    exports: {},
  };
  const require = (name) => {
    return packages[name];
  };
  // eslint-disable-next-line no-new-func
  Function('require, exports, module', code)(require, module.exports, module);
  return module;
};

const DynamicComponent = ({ name, children, ...props }) => {
  const Component = useMemo(() => {
    return React.lazy(async () => fetchComponent(name));
  }, [name]);

  return (
    <Suspense
      fallback={
        <div
          style={{ alignItems: 'center', justifyContent: 'center', flex: 1 }}
        >
          <span style={{ fontSize: 50 }}>Loading...</span>
        </div>
      }
    >
      <Component {...props}>{children}</Component>
    </Suspense>
  );
};

export default React.memo(DynamicComponent);
